using Bots.Grind;
using Buddy.Coroutines;

#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CommonBehaviors.Actions;
using Honorbuddy.QuestBehaviorCore;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.POI;
using Styx.CommonBot.Profiles;
using Styx.Helpers;
using Styx.Pathing;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
#endregion


// ReSharper disable once CheckNamespace
namespace Honorbuddy.Quest_Behaviors.Cava.KillWitchLordMorkurk
{
    [CustomBehaviorFileName(@"Cava\WoD-Kill-WitchLordMorkurk")]
    // ReSharper disable once UnusedMember.Global
    public class KillWitchLordMorkurk : CustomForcedBehavior
    {
        public KillWitchLordMorkurk(Dictionary<string, string> args)
            : base(args)
        {
            QBCLog.BehaviorLoggingContext = this;

            try
            {
                QuestId = GetAttributeAsNullable("QuestId", true, ConstrainAs.QuestId(this), null) ?? 0;
                QuestRequirementComplete = QuestCompleteRequirement.NotComplete;
                QuestRequirementInLog = QuestInLogRequirement.InLog;
            }

            catch (Exception except)
            {
                QBCLog.Exception(except);
                IsAttributeProblem = true;
            }
        }


        // Attributes provided by caller
        private int QuestId { get; set; }
        private QuestCompleteRequirement QuestRequirementComplete { get; set; }
        private QuestInLogRequirement QuestRequirementInLog { get; set; }

        // Private variables for internal state
        // ReSharper disable once UnassignedField.Compiler
        private bool _isBehaviorDone;
        // ReSharper disable once UnusedField.Compiler
        private Composite _root;

        // Private properties
        private static LocalPlayer Me { get { return (StyxWoW.Me); } }
        private WoWItem EmergencyRocketPack { get { return (StyxWoW.Me.CarriedItems.FirstOrDefault(i => i.Entry == 112307)); } }
        private WoWItem ScrollofMassTeleportation { get { return (StyxWoW.Me.CarriedItems.FirstOrDefault(i => i.Entry == 112543)); } }
        //private bool _usedScrollofMassTeleportation;
        private readonly WoWPoint _bossLoc = new WoWPoint(1178.352, 2017.988, 356.6444);
        private readonly WoWPoint _wallLoc = new WoWPoint(1182.195, 1979.664, 356.6816);
        private readonly WoWPoint _safeLocA = new WoWPoint(1167.44, 1990.139, 356.6046);
        private readonly WoWPoint _safeLocB = new WoWPoint(1191.222, 1994.544, 356.605);
        private readonly WoWPoint _safeLocDome = new WoWPoint(1171.7, 1997.26, 356.6092);
        private WoWGameObject Wall { get { return ObjectManager.GetObjectsOfType<WoWGameObject>().FirstOrDefault(r => r.Entry == 231090); } }
        private WoWUnit WitchLordMorkurk { get { return ObjectManager.GetObjectsOfType<WoWUnit>().Where(u => u.Entry == 80335).OrderBy(u => u.Distance).FirstOrDefault(); } }
        private WoWGameObject ArcaneNexus { get { return ObjectManager.GetObjectsOfType<WoWGameObject>().FirstOrDefault(r => r.Entry == 231056); } }
        private static bool IsQuestComplete(uint questId) { return Lua.GetReturnVal<bool>(string.Format("return IsQuestFlaggedCompleted({0})", questId), 0); }
        private static bool IsObjectiveComplete(int objectiveId, uint questId)
        {
            if (Me.QuestLog.GetQuestById(questId) == null)
            {
                return false;
            }
            var returnVal = Lua.GetReturnVal<int>(string.Format("return GetQuestLogIndexByID({0})", questId), 0);
            return
                Lua.GetReturnVal<bool>(string.Format("return GetQuestLogLeaderBoard({0},{1})", objectiveId, returnVal),
                    2);
        }
       
        #region Overrides of CustomForcedBehavior

        private Composite CreateBehavior_MainCombat()
        {
			return new ActionRunCoroutine(ctx => MainCoroutine());
        }

        // ReSharper disable once CSharpWarnings::CS1998
	    async Task<bool> MainCoroutine()
	    {
			if (!IsDone)
		    {
                //lootboss
		        if (WitchLordMorkurk != null && WitchLordMorkurk.IsDead && WitchLordMorkurk.Lootable)
		        {
                    QBCLog.Info("Looting Itens from Boss");
                    WitchLordMorkurk.Interact();
		            return false;
		        }

                //loot item
                if (ArcaneNexus != null && IsObjectiveComplete(1, (uint)QuestId))
		        {
                    QBCLog.Info("Interacting with Arcane Nexus");
		            if (ArcaneNexus.Location.Distance(Me.Location) > 4)
		                Navigator.MoveTo(ArcaneNexus.Location);
		            if (ArcaneNexus.Location.Distance(Me.Location) <= 4)
		            {
		                WoWMovement.MoveStop();
		                ArcaneNexus.Interact();
                        await Coroutine.Sleep(2000);
		            }
		            return false;
		        }

		        // se existe boss e wall espera
                if (WitchLordMorkurk != null && Wall != null && !Me.Combat)
			    {
                    QBCLog.Info("Waiting for combat");
                    Navigator.MoveTo(_wallLoc);
				    return true;
			    }

                // vai para o o local nao ha boss nem wall
                if (WitchLordMorkurk == null && Wall == null)
                {
                    QBCLog.Info("Moving to Boss Location");
                    Navigator.MoveTo(_bossLoc);
				    return false;
			    }

                // se possivel vai para junto do boss
                if (WitchLordMorkurk != null && WitchLordMorkurk.IsAlive && Wall == null && !Me.Combat)
		        {
		            QBCLog.Info("Moving to Boss To Start Combat");
                    Navigator.MoveTo(WitchLordMorkurk.Location);
		            return false;
		        }

		        // use scroll
		        /*if (WitchLordMorkurk != null && Wall != null && Me.Combat && !_usedScrollofMassTeleportation &&
		            Me.CarriedItems.Any(i => (i.Entry == 112543) && (i.Cooldown <= 0.0)))
		        {
                    QBCLog.Info("Using Scroll of Mass Teleportation");
                    ScrollofMassTeleportation.Use();
		            _usedScrollofMassTeleportation = true;
		            return false;
		        }*/
 
		        //avoid boss spells
                if (WitchLordMorkurk != null && WitchLordMorkurk.IsCasting && Me.Combat)
		        {
                    if (WitchLordMorkurk.IsCasting && WitchLordMorkurk.CastingSpellId == 168636 && WitchLordMorkurk.Location.Distance(_safeLocA) > WitchLordMorkurk.Location.Distance(_safeLocB))
		            {
	                    QBCLog.Info("Moving Safe Place");
		                Navigator.MoveTo(_safeLocA);
                        return true;
		            }
                    if (WitchLordMorkurk.IsCasting && WitchLordMorkurk.CastingSpellId == 168636 && WitchLordMorkurk.Location.Distance(_safeLocA) < WitchLordMorkurk.Location.Distance(_safeLocB))
		            {
		                QBCLog.Info("Moving Safe Place");
		                Navigator.MoveTo(_safeLocB);
                        return true;
		            }
                    if (WitchLordMorkurk.IsCasting && WitchLordMorkurk.CastingSpellId == 168770)
		            {
                        QBCLog.Info("Moving Behind boss");
                        Navigator.MoveTo(
                        WitchLordMorkurk.Location.RayCast(WitchLordMorkurk.Rotation + WoWMathHelper.DegreesToRadians(180), 6f));
                        return true;
		            }

		            if (IsQuestComplete(34569) || IsQuestComplete(34563))//TowerArsenal
		            {
                        // ReSharper disable once CompareOfFloatsByEqualityOperator
                        if (WitchLordMorkurk.IsCasting &&  WitchLordMorkurk.CastingSpellId == 162597 && !Me.HasAura(162896) && EmergencyRocketPack.Cooldown <= 0.0)
                        {
                            QBCLog.Info("Using Emergency Rocket Pack");
                            EmergencyRocketPack.Use();
                            return true;
                        }
                        if (Me.HasAura(162896)) return true;
		                return false;
		            }
		            if (IsQuestComplete(3463) || IsQuestComplete(34632)) //ArcaneSanctum
		            {
		                // ReSharper disable once CompareOfFloatsByEqualityOperator
		                if (WitchLordMorkurk.IsCasting && WitchLordMorkurk.CastingSpellId == 162597)
		                {
		                    if (ScrollofMassTeleportation.Cooldown <= 0.0)
		                    {
		                        QBCLog.Info("Using Scroll of Mass Teleportation");
		                        ScrollofMassTeleportation.Use();
		                    }
		                    QBCLog.Info("Moving to Under Dome");
		                    Navigator.MoveTo(_safeLocDome);
                            return true;
		                }
		                return false;
		            }
		            return false;
		        }

		        // se existe boss entramos em combate
                if (WitchLordMorkurk != null && WitchLordMorkurk.IsAlive && Wall != null && Me.Combat)
                {
                    if (WitchLordMorkurk != null && Me.CurrentTarget != WitchLordMorkurk)
                    {
                        QBCLog.Info("Killing Boss");
                        BotPoi.Current = new BotPoi(WitchLordMorkurk, PoiType.Kill);
                        WitchLordMorkurk.Target();
                        LevelBot.CreateCombatBehavior();
                    }
                    if (BotPoi.Current.Type != PoiType.Kill)
                    {
                        QBCLog.Info("Killing Boss");
                        BotPoi.Current = new BotPoi(WitchLordMorkurk, PoiType.Kill);
                        WitchLordMorkurk.Target();
                        LevelBot.CreateCombatBehavior();
                    }
                    return false;
                }
                return false;
		    }
		    return false;
	    }

        public override bool IsDone
        {
            get
            {
                return (_isBehaviorDone // normal completion
                        || !UtilIsProgressRequirementsMet(QuestId, QuestRequirementInLog, QuestRequirementComplete));
            }
        }

        public override void OnStart()
        {
            OnStart_HandleAttributeProblem();

            if (!IsDone)
            {
                TreeHooks.Instance.InsertHook("Combat_Main", 0, CreateBehavior_MainCombat());

                this.UpdateGoalText(QuestId);
            }
        }

	    public override void OnFinished()
	    {
            TreeHooks.Instance.RemoveHook("Combat_Main", CreateBehavior_MainCombat());
			TreeRoot.GoalText = string.Empty;
			TreeRoot.StatusText = string.Empty;
		    base.OnFinished();
	    }

	    #endregion
    }
}